using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Authorization;
using Microsoft.EntityFrameworkCore;
using AutoMapper;
using AiPlatformAdmin.Api.Data;
using AiPlatformAdmin.Api.Models;
using AiPlatformAdmin.Api.DTOs.Tenants;

namespace AiPlatformAdmin.Api.Controllers;

[ApiController]
[Route("api/[controller]")]
[Authorize(Roles = "SystemAdministrator")]
public class TenantsController : ControllerBase
{
    private readonly AppDbContext _context;
    private readonly IMapper _mapper;

    public TenantsController(AppDbContext context, IMapper mapper)
    {
        _context = context;
        _mapper = mapper;
    }

    [HttpGet]
    public async Task<ActionResult<IEnumerable<TenantDto>>> GetTenants()
    {
        var tenants = await _context.Tenants.ToListAsync();
        return Ok(_mapper.Map<IEnumerable<TenantDto>>(tenants));
    }

    [HttpGet("{id}")]
    public async Task<ActionResult<TenantDto>> GetTenant(int id)
    {
        var tenant = await _context.Tenants.FindAsync(id);

        if (tenant == null)
        {
            return NotFound(new { message = "Tenant not found" });
        }

        return Ok(_mapper.Map<TenantDto>(tenant));
    }

    [HttpPost]
    public async Task<ActionResult<TenantDto>> CreateTenant(CreateTenantDto dto)
    {
        // Check if tenant key already exists
        if (await _context.Tenants.AnyAsync(t => t.TenantKey == dto.TenantKey))
        {
            return BadRequest(new { message = "Tenant key already exists" });
        }

        var tenant = _mapper.Map<Tenant>(dto);

        _context.Tenants.Add(tenant);
        await _context.SaveChangesAsync();

        return CreatedAtAction(nameof(GetTenant), new { id = tenant.Id }, _mapper.Map<TenantDto>(tenant));
    }

    [HttpPut("{id}")]
    public async Task<IActionResult> UpdateTenant(int id, UpdateTenantDto dto)
    {
        var tenant = await _context.Tenants.FindAsync(id);

        if (tenant == null)
        {
            return NotFound(new { message = "Tenant not found" });
        }

        // Check tenant key uniqueness if changed
        if (dto.TenantKey != null && dto.TenantKey != tenant.TenantKey)
        {
            if (await _context.Tenants.AnyAsync(t => t.TenantKey == dto.TenantKey && t.Id != id))
            {
                return BadRequest(new { message = "Tenant key already exists" });
            }
        }

        _mapper.Map(dto, tenant);

        await _context.SaveChangesAsync();
        return NoContent();
    }

    [HttpDelete("{id}")]
    public async Task<IActionResult> DeleteTenant(int id)
    {
        var tenant = await _context.Tenants.FindAsync(id);

        if (tenant == null)
        {
            return NotFound(new { message = "Tenant not found" });
        }

        // Check if tenant has users
        if (await _context.Users.AnyAsync(u => u.TenantId == id))
        {
            return BadRequest(new { message = "Cannot delete tenant with existing users" });
        }

        _context.Tenants.Remove(tenant);
        await _context.SaveChangesAsync();

        return NoContent();
    }

    [HttpPatch("{id}/toggle")]
    public async Task<IActionResult> ToggleTenantStatus(int id)
    {
        var tenant = await _context.Tenants.FindAsync(id);

        if (tenant == null)
        {
            return NotFound(new { message = "Tenant not found" });
        }

        tenant.IsActive = !tenant.IsActive;
        await _context.SaveChangesAsync();

        return NoContent();
    }
}
